home *** CD-ROM | disk | FTP | other *** search
/ Cream of the Crop 26 / Cream of the Crop 26.iso / os2 / octa209s.zip / octave-2.09 / src / pt-pr-code.cc < prev    next >
C/C++ Source or Header  |  1997-03-07  |  19KB  |  1,190 lines

  1. /*
  2.  
  3. Copyright (C) 1996 John W. Eaton
  4.  
  5. This file is part of Octave.
  6.  
  7. Octave is free software; you can redistribute it and/or modify it
  8. under the terms of the GNU General Public License as published by the
  9. Free Software Foundation; either version 2, or (at your option) any
  10. later version.
  11.  
  12. Octave is distributed in the hope that it will be useful, but WITHOUT
  13. ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  14. FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  15. for more details.
  16.  
  17. You should have received a copy of the GNU General Public License
  18. along with Octave; see the file COPYING.  If not, write to the Free
  19. Software Foundation, 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
  20.  
  21. */
  22.  
  23. #if defined (__GNUG__)
  24. #pragma implementation
  25. #endif
  26.  
  27. #ifdef HAVE_CONFIG_H
  28. #include <config.h>
  29. #endif
  30.  
  31. #include <iostream.h>
  32.  
  33. #include "error.h"
  34. #include "pr-output.h"
  35. #include "pt-pr-code.h"
  36.  
  37. void
  38. tree_print_code::visit_argument_list (tree_argument_list& lst)
  39. {
  40.   Pix p = lst.first ();
  41.  
  42.   while (p)
  43.     {
  44.       tree_expression *elt = lst (p);
  45.  
  46.       lst.next (p);
  47.  
  48.       if (elt)
  49.     {
  50.       elt->accept (*this);
  51.  
  52.       if (p)
  53.         os << ", ";
  54.     }
  55.     }
  56. }
  57.  
  58. void
  59. tree_print_code::visit_binary_expression (tree_binary_expression& expr)
  60. {
  61.   indent ();
  62.  
  63.   bool in_parens = expr.is_in_parens ();
  64.  
  65.   if (in_parens)
  66.     os << "(";
  67.  
  68.   tree_expression *op1 = expr.lhs ();
  69.  
  70.   if (op1)
  71.     op1->accept (*this);
  72.  
  73.   os << " " << expr.oper () << " ";
  74.  
  75.   tree_expression *op2 = expr.rhs ();
  76.  
  77.   if (op2)
  78.     op2->accept (*this);
  79.  
  80.   if (in_parens)
  81.     os << ")";
  82. }
  83.  
  84. void
  85. tree_print_code::visit_break_command (tree_break_command&)
  86. {
  87.   indent ();
  88.  
  89.   os << "break";
  90. }
  91.  
  92. void
  93. tree_print_code::visit_builtin (tree_builtin& fcn)
  94. {
  95.   os << fcn.name ()
  96.      << " can't be printed because it is a built-in function\n";
  97. }
  98.  
  99. void
  100. tree_print_code::visit_colon_expression (tree_colon_expression& expr)
  101. {
  102.   indent ();
  103.  
  104.   bool in_parens = expr.is_in_parens ();
  105.  
  106.   if (in_parens)
  107.     os << "(";
  108.  
  109.   tree_expression *op1 = expr.base ();
  110.  
  111.   if (op1)
  112.     op1->accept (*this);
  113.  
  114.   // Stupid syntax.
  115.  
  116.   tree_expression *op3 = expr.increment ();
  117.  
  118.   if (op3)
  119.     {
  120.       os << ":";
  121.       op3->accept (*this);
  122.     }
  123.  
  124.   tree_expression *op2 = expr.limit ();
  125.  
  126.   if (op2)
  127.     {
  128.       os << ":";
  129.       op2->accept (*this);
  130.     }
  131.  
  132.   if (in_parens)
  133.     os << ")";
  134. }
  135.  
  136. void
  137. tree_print_code::visit_continue_command (tree_continue_command&)
  138. {
  139.   indent ();
  140.  
  141.   os << "continue";
  142. }
  143.  
  144. void
  145. tree_print_code::visit_for_command (tree_for_command& cmd)
  146. {
  147.   indent ();
  148.  
  149.   os << "for ";
  150.  
  151.   tree_index_expression *id = cmd.ident ();
  152.  
  153.   if (id)
  154.     id->accept (*this);
  155.  
  156.   os << " = ";
  157.  
  158.   tree_expression *expr = cmd.control_expr ();
  159.  
  160.   if (expr)
  161.     expr->accept (*this);
  162.  
  163.   newline ();
  164.  
  165.   tree_statement_list *list = cmd.body ();
  166.  
  167.   if (list)
  168.     {
  169.       increment_indent_level ();
  170.       list->accept (*this);
  171.       decrement_indent_level ();
  172.     }
  173.  
  174.   indent ();
  175.  
  176.   os << "endfor";
  177. }
  178.  
  179. void
  180. tree_print_code::visit_function (tree_function& fcn)
  181. {
  182.   reset ();
  183.  
  184.   visit_function_header (fcn);
  185.  
  186.   tree_statement_list *cmd_list = fcn.body ();
  187.  
  188.   if (cmd_list)
  189.     {
  190.       increment_indent_level ();
  191.       cmd_list->accept (*this);
  192.       decrement_indent_level ();
  193.     }
  194.  
  195.   visit_function_trailer (fcn);
  196. }
  197.  
  198. void
  199. tree_print_code::visit_function_header (tree_function& fcn)
  200. {
  201.   indent ();
  202.  
  203.   os << "function ";
  204.  
  205.   tree_parameter_list *ret_list = fcn.return_list ();
  206.  
  207.   if (ret_list)
  208.     {
  209.       bool takes_var_return = fcn.takes_var_return ();
  210.  
  211.       int len = ret_list->length ();
  212.  
  213.       if (len > 1 || takes_var_return)
  214.     os << "[";
  215.  
  216.       ret_list->accept (*this);
  217.  
  218.       if (takes_var_return)
  219.     {
  220.       if (len > 0)
  221.         os << ", ";
  222.  
  223.       os << "...";
  224.     }
  225.  
  226.       if (len > 1 || takes_var_return)
  227.     os << "]";
  228.  
  229.       os << " = ";
  230.     }
  231.  
  232.   string fcn_name = fcn.function_name ();
  233.  
  234.   os << (fcn_name.empty () ? string ("(empty)") : fcn_name) << " ";
  235.  
  236.   tree_parameter_list *param_list = fcn.parameter_list ();
  237.  
  238.   if (param_list)
  239.     {
  240.       bool takes_varargs = fcn.takes_varargs ();
  241.  
  242.       int len = param_list->length ();
  243.  
  244.       if (len > 0 || takes_varargs)
  245.     os << "(";
  246.  
  247.       param_list->accept (*this);
  248.  
  249.       if (takes_varargs)
  250.     {
  251.       if (len > 0)
  252.         os << ", ";
  253.  
  254.       os << "...";
  255.     }
  256.  
  257.       if (len > 0 || takes_varargs)
  258.     {
  259.       os << ")";
  260.       newline ();
  261.     }
  262.     }
  263.   else
  264.     {
  265.       os << "()";
  266.       newline ();
  267.     }
  268. }
  269.  
  270. void
  271. tree_print_code::visit_function_trailer (tree_function&)
  272. {
  273.   indent ();
  274.  
  275.   os << "endfunction";
  276.  
  277.   newline ();
  278. }
  279.  
  280. void
  281. tree_print_code::visit_global (tree_global& cmd)
  282. {
  283.   tree_identifier *id = cmd.ident ();
  284.  
  285.   if (id)
  286.     id->accept (*this);
  287.  
  288.   tree_simple_assignment_expression *ass_expr = cmd.assign_expr ();
  289.  
  290.   if (ass_expr)
  291.     ass_expr->accept (*this);
  292. }
  293.  
  294. void
  295. tree_print_code::visit_global_command (tree_global_command& cmd)
  296. {
  297.   indent ();
  298.  
  299.   os << "global ";
  300.  
  301.   tree_global_init_list *init_list = cmd.initializer_list ();
  302.  
  303.   if (init_list)
  304.     init_list->accept (*this);
  305. }
  306.  
  307. void
  308. tree_print_code::visit_global_init_list (tree_global_init_list& lst)
  309. {
  310.   Pix p = lst.first ();
  311.  
  312.   while (p)
  313.     {
  314.       tree_global *elt = lst (p);
  315.  
  316.       lst.next (p);
  317.  
  318.       if (elt)
  319.     {
  320.       elt->accept (*this);
  321.  
  322.       if (p)
  323.         os << ", ";
  324.     }
  325.     }
  326. }
  327.  
  328. void
  329. tree_print_code::visit_identifier (tree_identifier& id)
  330. {
  331.   indent ();
  332.  
  333.   bool in_parens = id.is_in_parens ();
  334.  
  335.   if (in_parens)
  336.     os << "(";
  337.  
  338.   string nm = id.name ();
  339.   os << (nm.empty () ? string ("(empty)") : nm);
  340.  
  341.   if (in_parens)
  342.     os << ")";
  343. }
  344.  
  345. void
  346. tree_print_code::visit_if_clause (tree_if_clause& cmd)
  347. {
  348.   tree_expression *expr = cmd.condition ();
  349.  
  350.   if (expr)
  351.     expr->accept (*this);
  352.  
  353.   newline ();
  354.  
  355.   increment_indent_level ();
  356.  
  357.   tree_statement_list *list = cmd.commands ();
  358.  
  359.   if (list)
  360.     {
  361.       list->accept (*this);
  362.  
  363.       decrement_indent_level ();
  364.     }
  365. }
  366.  
  367. void
  368. tree_print_code::visit_if_command (tree_if_command& cmd)
  369. {
  370.   indent ();
  371.  
  372.   os << "if ";
  373.  
  374.   tree_if_command_list *list = cmd.cmd_list ();
  375.  
  376.   if (list)
  377.     list->accept (*this);
  378.  
  379.   indent ();
  380.  
  381.   os << "endif";
  382. }
  383.  
  384. void
  385. tree_print_code::visit_if_command_list (tree_if_command_list& lst)
  386. {
  387.   Pix p = lst.first ();
  388.  
  389.   bool first_elt = true;
  390.  
  391.   while (p)
  392.     {
  393.       tree_if_clause *elt = lst (p);
  394.  
  395.       if (elt)
  396.     {
  397.       if (! first_elt)
  398.         {
  399.           indent ();
  400.  
  401.           if (elt->is_else_clause ())
  402.         os << "else";
  403.           else
  404.         os << "elseif ";
  405.         }
  406.  
  407.       elt->accept (*this);
  408.     }
  409.  
  410.       first_elt = false;
  411.       lst.next (p);
  412.     }
  413. }
  414.  
  415. void
  416. tree_print_code::visit_switch_case (tree_switch_case& cs)
  417. {
  418.   indent ();
  419.  
  420.   if (cs.is_default_case ())
  421.     os << "otherwise";
  422.   else
  423.     os << "case ";
  424.  
  425.   tree_expression *label = cs.case_label ();
  426.  
  427.   if (label)
  428.     label->accept (*this);
  429.  
  430.   newline ();
  431.  
  432.   increment_indent_level ();
  433.  
  434.   tree_statement_list *list = cs.commands ();
  435.  
  436.   if (list)
  437.     {
  438.       list->accept (*this);
  439.  
  440.       decrement_indent_level ();
  441.     }
  442. }
  443.  
  444. void
  445. tree_print_code::visit_switch_case_list (tree_switch_case_list& lst)
  446. {
  447.   Pix p = lst.first ();
  448.  
  449.   while (p)
  450.     {
  451.       tree_switch_case *elt = lst (p);
  452.  
  453.       if (elt)
  454.     elt->accept (*this);
  455.  
  456.       lst.next (p);
  457.     }
  458. }
  459.  
  460. void
  461. tree_print_code::visit_switch_command (tree_switch_command& cmd)
  462. {
  463.   indent ();
  464.  
  465.   os << "switch ";
  466.  
  467.   tree_expression *expr = cmd.switch_value ();
  468.  
  469.   if (expr)
  470.     expr->accept (*this);
  471.  
  472.   newline ();
  473.  
  474.   increment_indent_level ();
  475.  
  476.   tree_switch_case_list *list = cmd.case_list ();
  477.  
  478.   if (list)
  479.     list->accept (*this);
  480.  
  481.   indent ();
  482.  
  483.   os << "endswitch";
  484. }
  485.  
  486. void
  487. tree_print_code::visit_index_expression (tree_index_expression& expr)
  488. {
  489.   indent ();
  490.  
  491.   bool in_parens = expr.is_in_parens ();
  492.  
  493.   if (in_parens)
  494.     os << "(";
  495.  
  496.   tree_indirect_ref *id = expr.ident ();
  497.  
  498.   if (id)
  499.     id->accept (*this);
  500.  
  501.   tree_argument_list *list = expr.arg_list ();
  502.  
  503.   if (list)
  504.     {
  505.       os << " (";
  506.       list->accept (*this);
  507.       os << ")";
  508.     }
  509.  
  510.   if (in_parens)
  511.     os << ")";
  512. }
  513.  
  514. void
  515. tree_print_code::visit_indirect_ref (tree_indirect_ref& expr)
  516. {
  517.   indent ();
  518.  
  519.   bool in_parens = expr.is_in_parens ();
  520.  
  521.   if (in_parens)
  522.     os << "(";
  523.  
  524.   // The name of the indirect ref includes the sub-elements.
  525.  
  526.   string nm = expr.name ();
  527.   os << (nm.empty () ? string ("(empty)") : nm);
  528.  
  529.   if (in_parens)
  530.     os << ")";
  531. }
  532.  
  533. void
  534. tree_print_code::visit_matrix (tree_matrix& lst)
  535. {
  536.   indent ();
  537.  
  538.   bool in_parens = lst.is_in_parens ();
  539.  
  540.   if (in_parens)
  541.     os << "(";
  542.  
  543.   os << "[";
  544.  
  545.   Pix p = lst.first ();
  546.  
  547.   while (p)
  548.     {
  549.       tree_matrix_row *elt = lst (p);
  550.  
  551.       lst.next (p);
  552.  
  553.       if (elt)
  554.     {
  555.       elt->accept (*this);
  556.  
  557.       if (p)
  558.         os << "; ";
  559.     }
  560.     }
  561.  
  562.   os << "]";
  563.  
  564.   if (in_parens)
  565.     os << ")";
  566. }
  567.  
  568. void
  569. tree_print_code::visit_matrix_row (tree_matrix_row& lst)
  570. {
  571.   Pix p = lst.first ();
  572.  
  573.   while (p)
  574.     {
  575.       tree_expression *elt = lst (p);
  576.  
  577.       lst.next (p);
  578.  
  579.       if (elt)
  580.     {
  581.       elt->accept (*this);
  582.  
  583.       if (p)
  584.         os << ", ";
  585.     }
  586.     }
  587. }
  588.  
  589. void
  590. tree_print_code::visit_multi_assignment_expression
  591.   (tree_multi_assignment_expression& expr)
  592. {
  593.   indent ();
  594.  
  595.   bool in_parens = expr.is_in_parens ();
  596.  
  597.   if (in_parens)
  598.     os << "(";
  599.  
  600.   tree_return_list *lhs = expr.left_hand_side ();
  601.  
  602.   if (lhs)
  603.     {
  604.       int len = lhs->length ();
  605.  
  606.       if (len > 1)
  607.     os << "[";
  608.  
  609.       lhs->accept (*this);
  610.  
  611.       if (len > 1)
  612.     os << "]";
  613.     }
  614.  
  615.   os << " = ";
  616.  
  617.   tree_multi_val_ret *rhs = expr.right_hand_side ();
  618.  
  619.   if (rhs)
  620.     rhs->accept (*this);
  621.  
  622.   if (in_parens)
  623.     os << ")";
  624. }
  625.  
  626. void
  627. tree_print_code::visit_no_op_command (tree_no_op_command& cmd)
  628. {
  629.   indent ();
  630.  
  631.   os << cmd.original_command ();
  632. }
  633.  
  634. void
  635. tree_print_code::visit_oct_obj (tree_oct_obj&)
  636. {
  637.   ::error ("visit_oct_obj: internal error");
  638. }
  639.  
  640. void
  641. tree_print_code::visit_constant (tree_constant& val)
  642. {
  643.   indent ();
  644.  
  645.   bool in_parens = val.is_in_parens ();
  646.  
  647.   if (in_parens)
  648.     os << "(";
  649.  
  650.   val.print (os, true, print_original_text);
  651.  
  652.   if (in_parens)
  653.     os << ")";
  654. }
  655.  
  656. void
  657. tree_print_code::visit_parameter_list (tree_parameter_list& lst)
  658. {
  659.   Pix p = lst.first ();
  660.  
  661.   while (p)
  662.     {
  663.       tree_identifier *elt = lst (p);
  664.  
  665.       lst.next (p);
  666.  
  667.       if (elt)
  668.     {
  669.       elt->accept (*this);
  670.  
  671.       if (p)
  672.         os << ", ";
  673.     }
  674.     }
  675. }
  676.  
  677. void
  678. tree_print_code::visit_plot_command (tree_plot_command& cmd)
  679. {
  680.   indent ();
  681.  
  682.   int ndim = cmd.num_dimensions ();
  683.  
  684.   switch (ndim)
  685.     {
  686.     case 1:
  687.       os << "replot";
  688.       break;
  689.  
  690.     case 2:
  691.       os << "gplot";
  692.       break;
  693.  
  694.     case 3:
  695.       os << "gsplot";
  696.       break;
  697.  
  698.     default:
  699.       os << "<unkown plot command>";
  700.       break;
  701.     }
  702.  
  703.   plot_limits *range = cmd.limits ();
  704.  
  705.   if (range)
  706.     range->accept (*this);
  707.  
  708.   subplot_list *plot_list = cmd.subplots ();
  709.  
  710.   if (plot_list)
  711.     plot_list->accept (*this);
  712. }
  713.  
  714. void
  715. tree_print_code::visit_plot_limits (plot_limits& cmd)
  716. {
  717.   plot_range *x_range = cmd.x_limits ();
  718.  
  719.   if (x_range)
  720.     x_range->accept (*this);
  721.  
  722.   plot_range *y_range = cmd.y_limits ();
  723.  
  724.   if (y_range)
  725.     y_range->accept (*this);
  726.  
  727.   plot_range *z_range = cmd.z_limits ();
  728.  
  729.   if (z_range)
  730.     z_range->accept (*this);
  731. }
  732.  
  733. void
  734. tree_print_code::visit_plot_range (plot_range& cmd)
  735. {
  736.   os << " [";
  737.  
  738.   tree_expression *lower = cmd.lower_bound ();
  739.  
  740.   if (lower)
  741.     lower->accept (*this);
  742.  
  743.   os << ":";
  744.  
  745.   tree_expression *upper = cmd.upper_bound ();
  746.  
  747.   if (upper)
  748.     upper->accept (*this);
  749.  
  750.   os << "]";
  751. }
  752.  
  753. void
  754. tree_print_code::visit_postfix_expression (tree_postfix_expression& expr)
  755. {
  756.   indent ();
  757.  
  758.   bool in_parens = expr.is_in_parens ();
  759.  
  760.   if (in_parens)
  761.     os << "(";
  762.  
  763.   tree_identifier *id = expr.ident ();
  764.  
  765.   if (id)
  766.     id->accept (*this);
  767.  
  768.   os << expr.oper ();
  769.  
  770.   if (in_parens)
  771.     os << ")";
  772. }
  773.  
  774. void
  775. tree_print_code::visit_prefix_expression (tree_prefix_expression& expr)
  776. {
  777.   indent ();
  778.  
  779.   bool in_parens = expr.is_in_parens ();
  780.  
  781.   if (in_parens)
  782.     os << "(";
  783.  
  784.   os << expr.oper ();
  785.  
  786.   tree_identifier *id = expr.ident ();
  787.  
  788.   if (id)
  789.     id->accept (*this);
  790.  
  791.   if (in_parens)
  792.     os << ")";
  793. }
  794.  
  795. void
  796. tree_print_code::visit_return_command (tree_return_command&)
  797. {
  798.   indent ();
  799.  
  800.   os << "return";
  801. }
  802.  
  803. void
  804. tree_print_code::visit_return_list (tree_return_list& lst)
  805. {
  806.   Pix p = lst.first ();
  807.  
  808.   while (p)
  809.     {
  810.       tree_index_expression *elt = lst (p);
  811.  
  812.       lst.next (p);
  813.  
  814.       if (elt)
  815.     {
  816.       elt->accept (*this);
  817.  
  818.       if (p)
  819.         os << ", ";
  820.     }
  821.     }
  822. }
  823.  
  824. void
  825. tree_print_code::visit_simple_assignment_expression
  826.   (tree_simple_assignment_expression& expr)
  827. {
  828.   indent ();
  829.  
  830.   bool in_parens = expr.is_in_parens ();
  831.  
  832.   if (in_parens)
  833.     os << "(";
  834.  
  835.   if (! expr.is_ans_assign ())
  836.     {
  837.       tree_indirect_ref *lhs = expr.left_hand_side ();
  838.  
  839.       if (lhs)
  840.     lhs->accept (*this);
  841.  
  842.       tree_argument_list *index = expr.lhs_index ();
  843.  
  844.       if (index)
  845.     {
  846.       os << " (";
  847.       index->accept (*this);
  848.       os << ")";
  849.     }
  850.  
  851.       os << " = ";
  852.     }
  853.  
  854.   tree_expression *rhs = expr.right_hand_side ();
  855.  
  856.   if (rhs)
  857.     rhs->accept (*this);
  858.  
  859.   if (in_parens)
  860.     os << ")";
  861. }
  862.  
  863. void
  864. tree_print_code::visit_statement (tree_statement& stmt)
  865. {
  866.   tree_command *cmd = stmt.command ();
  867.  
  868.   if (cmd)
  869.     {
  870.       cmd->accept (*this);
  871.  
  872.       if (! stmt.print_result ())
  873.     os << ";";
  874.  
  875.       newline ();
  876.     }
  877.   else
  878.     {
  879.       tree_expression *expr = stmt.expression ();
  880.  
  881.       if (expr)
  882.     {
  883.       expr->accept (*this);
  884.  
  885.       if (! stmt.print_result ())
  886.         os << ";";
  887.  
  888.       newline ();
  889.     }
  890.     }
  891. }
  892.  
  893. void
  894. tree_print_code::visit_statement_list (tree_statement_list& lst)
  895. {
  896.   for (Pix p = lst.first (); p != 0; lst.next (p))
  897.     {
  898.       tree_statement *elt = lst (p);
  899.  
  900.       if (elt)
  901.     elt->accept (*this);
  902.     }
  903. }
  904.  
  905. void
  906. tree_print_code::visit_subplot (subplot& cmd)
  907. {
  908.   tree_expression *sp_plot_data = cmd.plot_data ();
  909.  
  910.   if (sp_plot_data)
  911.     {
  912.       os << " ";
  913.  
  914.       sp_plot_data->accept (*this);
  915.     }
  916.  
  917.   subplot_using *sp_using_clause = cmd.using_clause ();
  918.  
  919.   if (sp_using_clause)
  920.     sp_using_clause->accept (*this);
  921.  
  922.   tree_expression *sp_title_clause = cmd.title_clause ();
  923.  
  924.   if (sp_title_clause)
  925.     sp_title_clause->accept (*this);
  926.  
  927.   subplot_style *sp_style_clause = cmd.style_clause ();
  928.  
  929.   if (sp_style_clause)
  930.     sp_style_clause->accept (*this);
  931. }
  932.  
  933. void
  934. tree_print_code::visit_subplot_list (subplot_list& lst)
  935. {
  936.   Pix p = lst.first ();
  937.  
  938.   while (p)
  939.     {
  940.       subplot *elt = lst (p);
  941.  
  942.       lst.next (p);
  943.  
  944.       if (elt)
  945.     {
  946.       elt->accept (*this);
  947.  
  948.       if (p)
  949.         os << ",";
  950.     }
  951.     }
  952. }
  953.  
  954. void
  955. tree_print_code::visit_subplot_style (subplot_style& cmd)
  956. {
  957.   os << " with " << cmd.style ();
  958.  
  959.   tree_expression *sp_linetype = cmd.linetype ();
  960.  
  961.   if (sp_linetype)
  962.     {
  963.       os << " ";
  964.  
  965.       sp_linetype->accept (*this);
  966.     }
  967.  
  968.   tree_expression *sp_pointtype = cmd.pointtype ();
  969.  
  970.   if (sp_pointtype)
  971.     {
  972.       os << " ";
  973.  
  974.       sp_pointtype->accept (*this);
  975.     }
  976. }
  977.  
  978. void
  979. tree_print_code::visit_subplot_using (subplot_using& cmd)
  980. {
  981.   os << " using ";
  982.  
  983.   int qual_count = cmd.qualifier_count ();
  984.  
  985.   if (qual_count > 0)
  986.     {
  987.       tree_expression **x = cmd.qualifiers ();
  988.  
  989.       for (int i = 0; i < qual_count; i++)
  990.     {
  991.       if (i > 0)
  992.         os << ":";
  993.  
  994.       if (x[i])
  995.         x[i]->accept (*this);
  996.     }
  997.     }
  998.   else
  999.     {
  1000.       tree_expression *scanf_fmt = cmd.scanf_format ();
  1001.  
  1002.       if (scanf_fmt)
  1003.     scanf_fmt->accept (*this);
  1004.     }
  1005. }
  1006.  
  1007. void
  1008. tree_print_code::visit_try_catch_command (tree_try_catch_command& cmd)
  1009. {
  1010.   indent ();
  1011.  
  1012.   os << "try_catch";
  1013.  
  1014.   newline ();
  1015.  
  1016.   tree_statement_list *try_code = cmd.body ();
  1017.  
  1018.   if (try_code)
  1019.     {
  1020.       increment_indent_level ();
  1021.       try_code->accept (*this);
  1022.       decrement_indent_level ();
  1023.     }
  1024.  
  1025.   indent ();
  1026.  
  1027.   os << "catch";
  1028.  
  1029.   newline ();
  1030.  
  1031.   tree_statement_list *catch_code = cmd.cleanup ();
  1032.  
  1033.   if (catch_code)
  1034.     {
  1035.       increment_indent_level ();
  1036.       catch_code->accept (*this);
  1037.       decrement_indent_level ();
  1038.     }
  1039.  
  1040.   indent ();
  1041.  
  1042.   os << "end_try_catch";
  1043. }
  1044.  
  1045. void
  1046. tree_print_code::visit_unary_expression (tree_unary_expression& expr)
  1047. {
  1048.   indent ();
  1049.  
  1050.   bool in_parens = expr.is_in_parens ();
  1051.  
  1052.   if (in_parens)
  1053.     os << "(";
  1054.  
  1055.   tree_expression *op = expr.operand ();
  1056.  
  1057.   if (expr.is_prefix_op ())
  1058.     {
  1059.       os << expr.oper ();
  1060.  
  1061.       if (op)
  1062.     op->accept (*this);
  1063.     }
  1064.   else
  1065.     {
  1066.       if (op)
  1067.     op->accept (*this);
  1068.  
  1069.       os << expr.oper ();
  1070.     }
  1071.  
  1072.   if (in_parens)
  1073.     os << ")";
  1074. }
  1075.  
  1076. void
  1077. tree_print_code::visit_unwind_protect_command
  1078.   (tree_unwind_protect_command& cmd)
  1079. {
  1080.   indent ();
  1081.  
  1082.   os << "unwind_protect";
  1083.  
  1084.   newline ();
  1085.  
  1086.   tree_statement_list *unwind_protect_code = cmd.body ();
  1087.  
  1088.   if (unwind_protect_code)
  1089.     {
  1090.       increment_indent_level ();
  1091.       unwind_protect_code->accept (*this);
  1092.       decrement_indent_level ();
  1093.     }
  1094.  
  1095.   indent ();
  1096.  
  1097.   os << "cleanup_code";
  1098.  
  1099.   newline ();
  1100.  
  1101.   tree_statement_list *cleanup_code = cmd.cleanup ();
  1102.  
  1103.   if (cleanup_code)
  1104.     {
  1105.       increment_indent_level ();
  1106.       cleanup_code->accept (*this);
  1107.       decrement_indent_level ();
  1108.     }
  1109.  
  1110.   indent ();
  1111.  
  1112.   os << "end_unwind_protect";
  1113. }
  1114.  
  1115. void
  1116. tree_print_code::visit_while_command (tree_while_command& cmd)
  1117. {
  1118.   indent ();
  1119.  
  1120.   os << "while ";
  1121.  
  1122.   tree_expression *expr = cmd.condition ();
  1123.  
  1124.   if (expr)
  1125.     expr->accept (*this);
  1126.  
  1127.   newline ();
  1128.  
  1129.   tree_statement_list *list = cmd.body ();
  1130.  
  1131.   if (list)
  1132.     {
  1133.       increment_indent_level ();
  1134.       list->accept (*this);
  1135.       decrement_indent_level ();
  1136.     }
  1137.  
  1138.   indent ();
  1139.  
  1140.   os << "endwhile";
  1141. }
  1142.  
  1143. // Current indentation.
  1144. int tree_print_code::curr_print_indent_level = 0;
  1145.  
  1146. // Nonzero means we are at the beginning of a line.
  1147. bool tree_print_code::beginning_of_line = true;
  1148.  
  1149. // Each print_code() function should call this before printing
  1150. // anything.
  1151. //
  1152. // This doesn't need to be fast, but isn't there a better way?
  1153.  
  1154. void
  1155. tree_print_code::indent (void)
  1156. {
  1157.   assert (curr_print_indent_level >= 0);
  1158.  
  1159.   if (beginning_of_line)
  1160.     {
  1161.       os.form ("%s%*s", prefix.c_str (), curr_print_indent_level, "");
  1162.       beginning_of_line = false;
  1163.     }
  1164. }
  1165.  
  1166. // All print_code() functions should use this to print new lines.
  1167.  
  1168. void
  1169. tree_print_code::newline (void)
  1170. {
  1171.   os << "\n";
  1172.  
  1173.   beginning_of_line = true;
  1174. }
  1175.  
  1176. // For ressetting print_code state.
  1177.  
  1178. void
  1179. tree_print_code::reset (void)
  1180. {
  1181.   beginning_of_line = true;
  1182.   curr_print_indent_level = 0;
  1183. }
  1184.  
  1185. /*
  1186. ;;; Local Variables: ***
  1187. ;;; mode: C++ ***
  1188. ;;; End: ***
  1189. */
  1190.